home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 22 / Cream of the Crop 22.iso / program / cgazv3n4.zip / HELP-DIR.ZIP / HELP.C next >
C/C++ Source or Header  |  1989-07-13  |  8KB  |  286 lines

  1. /********************** HELP.C *********************************
  2. * Author: David Michmerhuizen
  3. *
  4. * Function: Provide pop-up help screens
  5. *
  6. * Compilers:    Turbo C  V1.5
  7. *
  8. * Memory models:    all
  9. *
  10. * Usage:
  11. *         #include <help.h>
  12. *
  13. *         ... your code ...
  14. *
  15. *         ... when help is desired, call help() ...
  16. *
  17. *              help(screen_numb);
  18. *
  19. *         ... where 'screen_numb' is a screen number
  20. *             defined in help.h.
  21. *
  22. ***************************************************************/
  23.  
  24. #include <conio.h>
  25. #include <stdio.h>
  26. #include <stdlib.h>
  27. #include <string.h>
  28.  
  29.  
  30. #define TRUE         1
  31. #define FALSE        0
  32.  
  33. #define MAX(a,b)        (((a)   > (b)) ? (a) : (b))
  34. #define MIN(a,b)        (((a)   < (b)) ? (a) : (b))
  35.  
  36.  
  37. #define MAXLINKS    20                          /* maximum links in 1 scrn  */
  38. #define LINKCHAR   '|'                          /* link delimiter character */
  39.  
  40.  
  41. typedef struct helplink_ {
  42.     int  x,y;
  43.     char *name;
  44. }
  45. HELPLINK;
  46.  
  47. typedef struct helpscreen_ {
  48.     char *name;
  49.     long pos;
  50.     int  len;
  51. }
  52. HELPSCREEN;
  53. /* files from makehelp.exe  */
  54. #include "help.h"                               /* #defined screen numbers  */
  55. #include "helpstru.h"                           /* screen xref structure    */
  56.  
  57.  
  58.  
  59.  
  60. /* machine specific I/O routines  (Turbo C 1.5, 2.x)  */
  61.  
  62. /* (getkey returns extended scan codes in the leftmost 8 bits of a word) */
  63.  
  64. #define GETKEY(i)  ( ((i) = getch()) ? (i) : ((i) |= (getch() << 8)))
  65.  
  66. #define DOWN_ARROW      20480
  67. #define UP_ARROW        18432
  68. #define LEFT_ARROW      19200
  69. #define RIGHT_ARROW     19712
  70. #define RETURN             13
  71. #define ESCAPE             27
  72.  
  73. #define SET_INTENSE()   textattr( (BLACK << 4) | WHITE)
  74. #define SET_NORMAL()    textattr( (BLACK << 4) | LIGHTGRAY)
  75. #define SET_REVERSE()   textattr( (LIGHTGRAY << 4) | BLACK)
  76.  
  77. #define CLS()               clrscr()
  78. #define DISP_CHAR(c)        putch(c)
  79. #define GOTOYX(y,x)         gotoxy(x,y);
  80. #define WHEREYX(y,x)        { x = wherex(); y = wherey(); }
  81. #define INVERT(s)           { SET_REVERSE(); cputs( s); SET_NORMAL(); }
  82. #define REVERT(s)           { SET_INTENSE(); cputs( s); SET_NORMAL(); }
  83. #define SAVE_SCREEN( y, x)  { WHEREYX(svy, svx); gettext( 1, 1, x, y, sbuff);}
  84. #define REST_SCREEN( y, x)  { puttext( 1, 1, x, y, sbuff); GOTOYX( svy, svx);}
  85. #define SCREEN_SIZE( y, x)  { struct text_info ti; gettextinfo( &ti);  \
  86.                               y = ti.screenheight; x = ti.screenwidth; }
  87.  
  88.  
  89.  
  90.  
  91.  
  92.  
  93. void help( unsigned int helpitem)
  94. {
  95.     char            *helpbuff = NULL;
  96.     char            *sbuff    = NULL;
  97.     FILE            *helpfile = NULL;
  98.     int             svx, svy;
  99.     char            *c;
  100.     HELPLINK        helplinks[ MAXLINKS];
  101.     int             i, item, newitem;
  102.     unsigned int    key;
  103.     int             linkactive = FALSE;
  104.     int             linkcount;
  105.     int             x,y;
  106.     unsigned int    sizex, sizey, sizescr;
  107.  
  108.  
  109.     /* help item number out of range ? */
  110.  
  111.     if  ( helpitem >= HELPSCREENS)
  112.     {
  113.         putchar('\x07');
  114.         return;
  115.     }
  116.  
  117.     SCREEN_SIZE( sizey, sizex);
  118.     sizescr = sizey * sizex;
  119.     if  ( !(sbuff = malloc( sizescr * 2)))
  120.     {
  121.         putchar('\x07');
  122.         return;
  123.     }
  124.  
  125.     if  ( !(helpbuff = malloc( sizescr)))
  126.     {
  127.         free( sbuff);
  128.         putchar('\x07');
  129.         return;
  130.     }
  131.  
  132.     if  ( !(helpfile = fopen( "help.hlp", "rb")))
  133.     {
  134.         free( sbuff);
  135.         free( helpbuff);
  136.         putchar('\x07');
  137.         return;
  138.     }
  139.  
  140.     SAVE_SCREEN( sizey, sizex);
  141.  
  142.     for(;;)                                     /* until user hits escape   */
  143.     {
  144.         /* test for valid number */
  145.  
  146.         if  ( helpitem >= HELPSCREENS)
  147.         {
  148.             putchar('\x07');
  149.             REST_SCREEN( sizey, sizex);
  150.             free( sbuff); free( helpbuff); fclose( helpfile);
  151.             return;
  152.         }
  153.  
  154.         /* go get screen from help data file */
  155.  
  156.         if  ( fseek( helpfile, helpscreens[helpitem].pos, SEEK_SET) == -1L)
  157.         {
  158.             putchar('\x07');
  159.             REST_SCREEN( sizey, sizex);
  160.             free( sbuff); free( helpbuff); fclose( helpfile);
  161.             return;
  162.         }
  163.         fread( helpbuff, 1,
  164.             MIN(helpscreens[helpitem].len, sizescr),
  165.             helpfile);
  166.  
  167.         helpbuff[ helpscreens[ helpitem].len] = '\0';
  168.  
  169.         /* display screen, building array of links */
  170.  
  171.         SET_NORMAL();
  172.         CLS();
  173.         x = y = 1;
  174.         linkcount = 0;
  175.         for ( c = helpbuff; *c; c++)
  176.         {
  177.             if  ( *c == '\n')
  178.             {
  179.                 x = 1;
  180.                 y++;
  181.                 continue;
  182.             }
  183.  
  184.             /* start or stop of link */
  185.  
  186.             if  ( *c == LINKCHAR)
  187.             {
  188.                 if  ( !linkactive)
  189.                 {
  190.                     helplinks[linkcount].x = x;
  191.                     helplinks[linkcount].y = y;
  192.                     helplinks[linkcount].name = c+1;
  193.                     linkcount++;
  194.                     SET_INTENSE();
  195.                 }
  196.                 else
  197.                 {
  198.                     *c = '\0';
  199.                     SET_NORMAL();
  200.                 }
  201.                 linkactive = !linkactive;
  202.                 continue;
  203.             }
  204.  
  205.             /* actually display characters (\xFF signals repeated character) */
  206.  
  207.             i = (*c == '\xFF') ? (++c, *(c++)) : 1;
  208.             while(i--)
  209.             {
  210.                 GOTOYX( y, x);
  211.                 DISP_CHAR( *c);
  212.                 x++;
  213.             }
  214.         }
  215.  
  216.         /*
  217.         ** screen is set up.
  218.         ** now allow the user to cursor through the onscreen links,
  219.         ** inverting the active link and allowing return
  220.         ** to select the active link or esc to exit
  221.         */
  222.  
  223.         if  ( !linkcount)
  224.         {
  225.             GETKEY( key);
  226.             REST_SCREEN( sizey, sizex);
  227.             free( sbuff); free( helpbuff); fclose( helpfile);
  228.             return;
  229.         }
  230.  
  231.         newitem = item = 0;
  232.         GOTOYX( helplinks[item].y, helplinks[item].x);
  233.         INVERT( helplinks[item].name);
  234.         do
  235.         {
  236.             if  ( newitem != item)
  237.             {
  238.                 GOTOYX( helplinks[item].y, helplinks[item].x);
  239.                 REVERT( helplinks[item].name);
  240.                 GOTOYX( helplinks[newitem].y, helplinks[newitem].x);
  241.                 INVERT( helplinks[newitem].name);
  242.                 item = newitem;
  243.             }
  244.             GETKEY(key);
  245.             switch(key)
  246.             {
  247.                 case  DOWN_ARROW:
  248.                 case  RIGHT_ARROW:
  249.                     if  ( ++newitem >= linkcount)
  250.                         newitem = 0;
  251.                     break;
  252.  
  253.                 case  UP_ARROW:
  254.                 case  LEFT_ARROW:
  255.                     if  ( --newitem < 0)
  256.                         newitem = linkcount-1;
  257.                     break;
  258.  
  259.                 case ESCAPE:
  260.                     REST_SCREEN( sizey, sizex);
  261.                     free( sbuff); free( helpbuff); fclose( helpfile);
  262.                     return;
  263.  
  264.                 default:
  265.                     break;
  266.             }
  267.         }
  268.         while ( key != RETURN);
  269.  
  270.         /* user pressed return. look up link in link array */
  271.  
  272.         for( i=0; i < HELPSCREENS; i++)
  273.         {
  274.             if  ( !stricmp( helplinks[item].name, helpscreens[i].name))
  275.                 break;
  276.         }
  277.  
  278.         /* if link not found, do nothing. */
  279.  
  280.         if  ( i < HELPSCREENS)
  281.             helpitem = i;
  282.     }
  283.  
  284. } /* end of help */
  285.  
  286.